import { App } from "vue"
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router"
import LoginVue from "../views/Login/index.vue"
import { useUserStore } from "@/store"
import { user } from "@/api"
const routes: RouteRecordRaw[] = [
    {
        path: "/login",
        name: "login",
        // 一般来说，项目的第一个进入的页面不用 路由懒加载
        component: LoginVue
    },

]


const router = createRouter({
    history: createWebHashHistory(),
    routes
})
// 一般控制动态的路由是写在 全局前置守卫里面
router.beforeEach((to, from, next) => {

    // 判断是否登录 看有没有存储token
    const token = localStorage.getItem("token")
    // 使用pinia中的数据
    const userStore = useUserStore()

    // 登录成功 有了token，但是没有存储在pinia里面，重新发起请求 
    // from.path === "/" 刷新时候 from会显示 '/'   
    //  当然from.path=="/login" 为加入登录页面
    // 没有登录，并且不是登录页面
    if (!token && to.path !== "/login") {
        next('/login')

    } else if (token && to.path === "/login") {
        // 登录了 ，直接通过路径想重新访问登录页面， 强制返回当前页面
        next(from.path)
    }
    //   如果是刷新后，from.path 永远是 /
    else if (token && userStore.menus.length === 0 &&
        router.getRoutes().length === 1
        && (from.path === "/login" || from.path === "/")) {
        // 登录了但是数据没有渲染到页面上
        user.userDataApi().then(res => {
            if (res.code === 200) {
                // 将该用户所有的菜单数据存储在pinia
                userStore.menus = res.data.menus
                // 将用户的名称存储在pinia
                userStore.username = res.data.username
                // 为了不和store里面的数据冲突，把数据进行一份拷贝
                const menus: IMenu[] = JSON.parse(JSON.stringify(res.data.menus));

                const parents: IActiveMenu[] = menus.filter(
                    (menu) => menu.parentId === 0
                );
                // 修饰请求回来的数据 获取一级路由并且将一级路由的二级路由存储在一级路由中
                menus.forEach((menu) => {
                    // p 就是就一级路由 
                    const p = parents.find((p) => p.id === menu.parentId);
                    if (p) {
                        if (!p.children) {
                            p.children = [];
                        }
                        p.children.push(menu);
                    }
                });
                // 上一步已经获取到   菜单数据回来了，可以生成动态路由了
                parents.forEach((parent) => {
                    const route: RouteRecordRaw = {
                        // parent是一级菜单
                        path: "/" + parent.name,
                        name: parent.name,
                        component: () => import("../views/Home/index.vue"),
                        children: [],
                        // 添加字段做一级面包屑
                        meta: {
                            title: parent.title,
                        },
                    }
                    //   然后添加子路由
                    parent.children?.forEach(child => {
                        route.children?.push(
                            {
                                // path ===>  /一级/二级
                                path: `/${parent.name}/${child.name}`,
                                name: child.name,
                                component: () => import(`../views/${parent.name}/${child.name}.vue`),
                                //  /一级/二级
                                meta: {
                                    title: child.title,
                                },
                            });
                    });
                    // addRoute方法添加路由配置不是同步生效的，需要我们等等再进入
                    router.addRoute(route)

                });
                router.addRoute({
                    path: "/",
                    name: "home",
                    redirect: "/index",
                    component: () => import("../views/Home/index.vue"),
                    children: [
                        {
                            path: "/index",
                            name: "index",
                            component: () => import("../views/index/index.vue"),
                        },
                    ],
                });
                next(to.path);
            }
        });

    } else {
        next()
    }
});

export default (app: App<Element>) => {
    app.use(router)
}
export { router } 